perm filename COLOR.SAI[SYS,HE] blob sn#004177 filedate 1972-07-12 generic text, type T, neo UTF8
COMMENT ⊗   VALID 00007 PAGES 
RECORD PAGE   DESCRIPTION
 00001 00001
 00003 00002	BEGIN "COLOR"
 00007 00003	⊃	MESSAGE PROCEDURE ENTRY
 00010 00004		SIMPLE PROCEDURE LOWER_SENSITIVITY
 00018 00005		PROCEDURE COLOR_CHOICE(INTEGER PT)
 00020 00006		PROCEDURE COLOR_RANGE(INTEGER SAMPLES)
 00024 00007		LABEL CLG,RDAC
 00026 ENDMK
⊗;
BEGIN "COLOR"
REQUIRE "PREAMB.SAI[SYS,HE]" SOURCE_FILE;
REQUIRE -1 NEW_ITEMS;
REQUIRE "HELIB[1,3]" LIBRARY;
REQUIRE "SQRT[SYS,HE]" LOAD_MODULE;

EXTERNAL PROCEDURE TVIN;
EXTERNAL PROCEDURE INTPNT;
EXTERNAL INTEGER PROCEDURE GIOWD(INTEGER ARRAY X);
EXTERNAL INTEGER PROCEDURE POTABS(INTEGER CHAN; REFERENCE INTEGER FLAG);
EXTERNAL INTEGER PROCEDURE DDACO(INTEGER I);
EXTERNAL PROCEDURE CWHEEL(INTEGER I);
EXTERNAL REAL PROCEDURE SQRT(REAL X);
EXTERNAL INTEGER PROCEDURE GENTER(INTEGER X,Y,U,Q);

EXTERNAL INTEGER TVWORD,FLINE,LLINE,RSIDE,LSIDE,STVFL, TMAX,BMAX,LSMAX,RSMAX,TCLIP,BCLIP;
INTEGER ARRAY TVBUF[1:8000];
PRELOAD_WITH "RED","BLUE","GREEN","WHITE";
STRING ARRAY COLOR_NAME[0:3];
INTEGER I, NEWDAC;
INTEGER ITEMVAR ARRAY XCOLOR[0:3];
STRING SCRNAM;
DEFINE CRLF="('15&'12)", MSG= ")", EOM= "&CRLF MSG",⊃="COMMENT",
	ITYPE(FOO)="BEGIN IF TYP_COL THEN OUTSTR(""FOO""&"" ""&CVS(FOO)&CRLF)END",
	RTYPE(FOO)="BEGIN IF TYP_COL THEN OUTSTR(""FOO""&"" ""&CVG(FOO)&CRLF)END",
	TVRESET="STVFL←0"; COMMENT EFFECTIVELY ZEROS TV BUFFER;

⊃	THIS ROUTINE IS DESIGNED TO AID INTERACTIVE
		ON LINE EXPERIMENTATION BY ENABLING THE USER TO
		GET COLORS AT ANY PART OF THE IMAGE;

PROCEDURE POINTINFO;
	BEGIN "POINT"
	INTEGER SFL3,SLL3,SRS3,SLS3,XPOT,YPOT,ERRFLAG;
	SLL3 ← (SFL3 ← (FLINE+LLINE)/2+1)+2;
	SRS3 ← (SLS3 ← (LSIDE+RSIDE)/2+1)+2;
	OUTSTR("ADJUST CURSOR WITH POTS, Y TO EXIT" EOM;
	WHILE TRUE DO
		BEGIN "ADJUST"
		FLINE ← SFL3;
		LLINE ← SLL3;
		LSIDE ← SLS3;
		RSIDE ← SRS3;
		TVIN;
		IF INCHRS="Y" THEN RETURN;
		XPOT←POTABS(1,ERRFLAG);
		IF ERRFLAG THEN BEGIN OUTSTR("ERROR IN XPOT" EOM;RETURN; END;
		YPOT←POTABS(2,ERRFLAG);
		IF ERRFLAG THEN BEGIN OUTSTR("ERROR IN YPOT" EOM; RETURN; END;
		IF 5<(SFL3←125-YPOT/15)<250 THEN SLL3←SFL3+2 ELSE SFL3←SLL3-2;
		IF 5<(SLS3←165+XPOT/12)<330 THEN SRS3←SLS3+2 ELSE SLS3←SRS3-2;
		END "ADJUST";
	END "POINT";
⊃	MESSAGE PROCEDURE ENTRY;

MESSAGE PROCEDURE CLR_GET(INTEGER SAMPLES; REAL ARRAY POINTS);	
	BEGIN "GET"	
	INTEGER SAMPLE,FILTER,COLOR, XMIN,XMAX,YMIN,YMAX,X1,X2,
		LAST_VOLTAGE,TARGET_SUM,SUMSQ,TARGET_VOLTAGE,
		RAISE_SENS,LOWER_SENS;
	LABEL GEND;
	DEFINE DAC_INIT="36",DAC_MAX="63",DAC_STEPUP="1", NMAX="32",
		DAC_STEPDOWN="3",VOLTAGE_STEP="150",VOLTAGE_ERRSQ="700";
	REAL ARRAY LIGHT[1:NMAX,0:2];
	INTEGER ITEMVAR ARRAY ANSWER[1:NMAX];

	⊃ DAC_INIT IS SOMEWHAT CRITICAL;

	REAL NEAR_WHITE;
	DEFINE LAST_SAMPLE="3",FIRST_SAMPLE="0";
	DEFINE WHITE_SAMPLE="3",RED_SAMPLE="0",
		BLUE_SAMPLE="1",GREEN_SAMPLE="2";
	DEFINE WHITE_FILTER="3",RED_FILTER="0",
			BLUE_FILTER="1",GREEN_FILTER="2";
	REAL ARRAY EXAMPLE[FIRST_SAMPLE:LAST_SAMPLE,1:2];
	REAL ARRAY SPECIMEN[FIRST_SAMPLE:LAST_SAMPLE,1:2];

	SIMPLE PROCEDURE COLOR_INIT;
		BEGIN "INIT"
		REAL NORM,I,J;
		NEAR_WHITE←.07*.07;
		SPECIMEN[WHITE_SAMPLE,BLUE_FILTER]←0.36;
		SPECIMEN[WHITE_SAMPLE,GREEN_FILTER]←0.31;

		SPECIMEN[RED_SAMPLE,BLUE_FILTER]←0.15;
		SPECIMEN[RED_SAMPLE,GREEN_FILTER]←0.15;

		SPECIMEN[BLUE_SAMPLE,BLUE_FILTER]←.60;
		SPECIMEN[BLUE_SAMPLE,GREEN_FILTER]←.27;

		SPECIMEN[GREEN_SAMPLE,BLUE_FILTER]←.31;
		SPECIMEN[GREEN_SAMPLE,GREEN_FILTER]←.55;

	⊃ SET UP NORMALIZED COLOR VECTORS;

		FOR SAMPLE←FIRST_SAMPLE STEP 1 UNTIL LAST_SAMPLE DO
			BEGIN "LOOP"
			I←SPECIMEN[SAMPLE,BLUE_FILTER]-SPECIMEN[WHITE_SAMPLE,BLUE_FILTER];
			J←SPECIMEN[SAMPLE,GREEN_FILTER]-SPECIMEN[WHITE_SAMPLE,GREEN_FILTER];
			NORM←SQRT(I*I+J*J);
			EXAMPLE[SAMPLE,BLUE_FILTER]←I/NORM;
			EXAMPLE[SAMPLE,GREEN_FILTER]←J/NORM;
			END "LOOP";
		END "INIT";
	SIMPLE PROCEDURE LOWER_SENSITIVITY;
		BEGIN
		NEWDAC←DAC_ACC+DAC_STEPDOWN;
		IF NEWDAC>DAC_MAX THEN NEWDAC←DAC_MAX;
		END;

	SIMPLE PROCEDURE SCAN_WINDOW(REAL ARRAY POINTS;INTEGER SAMPLES);
		BEGIN "WINDOW"
		XMIN←XMAX←POINTS[1,1];
		YMIN←YMAX←POINTS[2,1];
		FOR SAMPLE←2 STEP 1 UNTIL SAMPLES DO
			BEGIN "LOOP"
			X1←POINTS[1,SAMPLE];
			X2←POINTS[2,SAMPLE];
		 	IF(XMAX<X1)THEN XMAX←X1;
			IF(XMIN>X1)THEN XMIN←X1;
			IF(YMAX<X2)THEN YMAX←X2;
			IF(YMIN>X2)THEN YMIN←X2;
			END "LOOP";
		TMAX ← FLINE←YMIN-3;
		BMAX ← LLINE←YMAX+3;
		LSMAX ← LSIDE←XMIN-3;
		RSMAX ← RSIDE←XMAX+3;
		END "WINDOW";

	SIMPLE REAL PROCEDURE TVREAD(INTEGER I,J);
		BEGIN "TVR"
		INTEGER K,L,M,N,SUM;
		SUM←0;
		FOR K←I-1,I,I+1 DO
		FOR L←J-1,J,J+1 DO SUM←SUM+GENTER(K,L,M,M);
		RETURN (SUM/9.0);
		END "TVR";

	SIMPLE PROCEDURE COLOR_INPUT(INTEGER COLOR,SAMPLES;REAL ARRAY POINTS);
		BEGIN "INPUT"
		REAL X;
		INTEGER N;
		CWHEEL(COLFILT_ACC ← COLOR);
		N ← 12000;
		WHILE N DO N←N-1;
		TARGET_VOLTAGE←DDACO(-1)*3;
		ITYPE(TARGET_VOLTAGE);
		FOR SAMPLE←1 STEP 1 UNTIL SAMPLES DO
		LIGHT[SAMPLE,COLOR]←0;

	⊃ READ USING SUB_RANGING FOR BETTER ACCURACY;

		FOR TCLIP←0,2,4,6 DO
			BEGIN
			BCLIP←TCLIP+1;
			TVRESET;
			TVIN;
			FOR SAMPLE←1 STEP 1 UNTIL SAMPLES DO
				BEGIN
				X←TVREAD(POINTS[1,SAMPLE],POINTS[2,SAMPLE]);
				LIGHT[SAMPLE,COLOR]←LIGHT[SAMPLE,COLOR]+X/4.0;
				END;
			END;
		END "INPUT";

	SIMPLE REAL PROCEDURE SAME_VOLTAGE(REAL ARRAY POINTS;INTEGER SAMPLES);
		⊃ READ AT COMMON TARGET VOLTAGE;
		BEGIN "SAME"
		TARGET_SUM←SUMSQ←0;
		FOR FILTER←RED_FILTER,BLUE_FILTER,GREEN_FILTER DO
			BEGIN
			DDACO(NEWDAC);
			COLOR_INPUT(FILTER,SAMPLES,POINTS);
			TARGET_SUM←TARGET_SUM+TARGET_VOLTAGE;
			SUMSQ←SUMSQ+TARGET_VOLTAGE↑2;
			END;
	 	ITYPE(TARGET_SUM);
		ITYPE(SUMSQ);
		SUMSQ←-(TARGET_SUM*TARGET_SUM-3*SUMSQ);
		ITYPE(SUMSQ);
		RETURN(VOLTAGE_ERRSQ-SUMSQ);
		END "SAME";


	SIMPLE STRING PROCEDURE NAME(ITEMVAR FOO);
		BEGIN
		INTEGER F;
		STRING S;
		S ← CVIS(FOO,F);
		IF F THEN S ← CVOS(CVN(FOO));
		RETURN(S);
		END;
	PROCEDURE COLOR_CHOICE(INTEGER PT);
		BEGIN "CHOICE"
		LABEL LOOP;
		INTEGER COLOR,SAMPLE;
		REAL MAX,SUM,B,G,I,J;
		ITYPE(PT);
		SUM←0;
		FOR FILTER ←0,1,2 DO BEGIN G←LIGHT[PT,FILTER];RTYPE(G);END;

	⊃ VIDICON CORRECTION VOLTS=LIGHT↑GAMMA

		LIGHT=VOLTS↑(1/GAMMA);
		FOR FILTER←0,1,2 DO
			BEGIN
			I←LIGHT[PT,FILTER]←LIGHT[PT,FILTER]↑1.54;
			RTYPE(I);
			SUM←SUM+I;
			END;

	⊃ CALCULATE COLOR RATIOS;

		B←LIGHT[PT,BLUE_FILTER]/SUM;
		G←LIGHT[PT,GREEN_FILTER]/SUM;
		RTYPE(B);
		RTYPE(G);
		I←B-SPECIMEN[WHITE_SAMPLE,BLUE_FILTER];
		J←G-SPECIMEN[WHITE_SAMPLE,GREEN_FILTER];
		RTYPE(I);
		RTYPE(J);

	⊃ TEST FOR WHITE;

		IF I*I+J*J<NEAR_WHITE THEN ANSWER[PT]←XCOLOR[COLOR←WHITE_SAMPLE] ELSE
			BEGIN "CLOOP"

			⊃ CHOOSE THE NEAREST PROTOTYPE COLOR (MAX DOT PROD WITH NORMED VECTOR);

			MAX←0;
			COLOR←-1;
			FOR SAMPLE←FIRST_SAMPLE STEP 1 UNTIL LAST_SAMPLE DO
				BEGIN
				IF SAMPLE=WHITE_SAMPLE THEN GO LOOP;
				SUM←I*EXAMPLE[SAMPLE,BLUE_FILTER]+J*EXAMPLE[SAMPLE,GREEN_FILTER];
				IF SUM>MAX THEN BEGIN COLOR←SAMPLE;MAX←SUM;END;
LOOP:				END;
			IF COLOR≥0 THEN ANSWER[PT]←XCOLOR[COLOR];
			END "CLOOP";     
		ITYPE(COLOR);
	END "CHOICE";
	PROCEDURE COLOR_RANGE(INTEGER SAMPLES);
		BEGIN "RANGE"
		LABEL REND;
		REAL LOW,HIGH;
	⊃ SELECT SAMPLES W/ COMPLETE MEASUREMENTS
	SELECT LOW HIGH-CLIPPED AND HIGH LOW-CLIPPED;
		ITYPE(SAMPLES);
		RAISE_SENS←LOWER_SENS←0;
		FOR SAMPLE←1 STEP 1 UNTIL SAMPLES DO
			BEGIN
			IF ANSWER[SAMPLE]≠NIL THEN GO REND;
			LOW←HIGH←LIGHT[SAMPLE,RED_FILTER];
			FOR COLOR←BLUE_FILTER,GREEN_FILTER DO
				BEGIN
				IF(LIGHT[SAMPLE,COLOR]>HIGH)THEN
					HIGH←LIGHT[SAMPLE,COLOR];
				IF(LIGHT[SAMPLE,COLOR]<LOW)THEN
					LOW←LIGHT[SAMPLE,COLOR];
				END;
			IF(HIGH>0.7)∧(HIGH<14.5)THEN COLOR_CHOICE(SAMPLE);
			IF(HIGH≤0.7)THEN RAISE_SENS←1;
			IF(HIGH≥14.5)THEN LOWER_SENS←1;
REND:			ITYPE(SAMPLE);
			RTYPE(LOW);
			RTYPE(HIGH);
			END;
		END "RANGE";

	⊃ INITIALIZE VARIOUS THINGS - START OF BODY OF CLR_GET;

	COLOR_INIT;
	SCAN_WINDOW(POINTS,SAMPLES);
	INTPNT;
	FOR SAMPLE←1 STEP 1 UNTIL SAMPLES DO ANSWER[SAMPLE]←NIL;


	⊃ ACCOMODATION PACKAGE
		START AT A LOW TARGET VOLTAGE VALUE(CRITICAL)
		FIND COMMON VOLTAGE FOR THREE FILTERS
		RAISE SENSITIVITY IF ANY SAMPLES LOW_CLIPPED
		LOWER SENSITIVITY IF ANY SAMPLES HIGH_CLIPPED;

	NEWDAC ← AUTO_ACC; ⊃	THIS IS TEMP UNTIL BUG IN SAIL IS FIXED;
	NEWDAC←DAC_INIT;
	WHILE(SAME_VOLTAGE(POINTS,SAMPLES)<0)∧(NEWDAC<DAC_MAX) DO LOWER_SENSITIVITY;
	COLOR_RANGE(SAMPLES);⊃ CHOOSE COLORS FOR THOSE SAMPLES IN RANGE;
	WHILE RAISE_SENS>0 DO
		BEGIN
		LAST_VOLTAGE←TARGET_SUM;
		NEWDAC←DAC_ACC-DAC_STEPUP;
		RAISE_SENS←0;
                IF SAME_VOLTAGE(POINTS,SAMPLES)>0
			∧ TARGET_SUM<(LAST_VOLTAGE-VOLTAGE_STEP)
 			THEN  COLOR_RANGE(SAMPLES);
		END;
	WHILE (LOWER_SENS>0)∧(NEWDAC<DAC_MAX) DO
		BEGIN
		LOWER_SENSITIVITY;
		SAME_VOLTAGE(POINTS,SAMPLES);
		COLOR_RANGE(SAMPLES);
		END;
GEND:	IF RUN THEN ISSUE(5,"COL",SCRNAM,MESSAGE CLR_RESPONSE(ANSWER)) ELSE
		FOR I←1 STEP 1 UNTIL SAMPLES DO OUTSTR(NAME(ANSWER[I])&CRLF);
	END "GET";
	LABEL CLG,RDAC;
	REAL ARRAY POINTS[1:2,1:32];
	INTEGER SAMPLES;
	XCOLOR[0] ← RED;
	XCOLOR[1] ← BLUE;
	XCOLOR[2] ← GREEN;
	XCOLOR[3] ← WHITE;
	SETFORMAT(0,4);
	TVWORD←GIOWD(TVBUF);
	SAMPLES←0;
	PUT_DATA(0,0,"COL");
	YES_COL ← TRUE;
	IF RUN THEN WHILE TRUE DO
		BEGIN
		I ← GET_ENTRY('120,NULL,"COL",NULL);
		SCRNAM ← GET_DATA(1,I);
		QUEUE('600,I);
		END ELSE
RDAC:		WHILE TRUE DO
		BEGIN
		OUTSTR("ANOTHER VOLTAGE? Y OR N"&CRLF EOM;
		IF INCHWL="N" THEN DONE;
		I←INTSCAN(SCRNAM←INCHWL,I);
		I ← DDACO(I);
		ITYPE(DAC_ACC);
		ITYPE(I);
		END;
	WHILE TRUE DO
		BEGIN
		OUTSTR("ANOTHER POINT? Y OR N"&CRLF EOM;
		IF INCHWL="N" THEN DONE;
		SAMPLES←SAMPLES+1;
		POINTINFO;
		ITYPE(SAMPLES);
		POINTS[1,SAMPLES]←LSIDE;
		POINTS[2,SAMPLES]←FLINE;
		END;
CLG:	CLR_GET(SAMPLES,POINTS);
	OUTSTR("REPEAT? Y OR N" EOM;
	IF INCHWL="Y" THEN GO CLG;
	END "COLOR";